import os
import ssl

from .app import Flask
from app.cache.base import RedisClient, RedisClientRemote, RedisClientAccount
from flask import request, g
import logging
import json
import time
from concurrent.futures import ThreadPoolExecutor

ssl._create_default_https_context = ssl._create_unverified_context
executor = ThreadPoolExecutor(20)
redisclient = RedisClient()
redisclientRemote = RedisClientRemote()
redisclientAccount = RedisClientAccount()


def make_dir(make_dir_path):
    path = make_dir_path.strip()
    if not os.path.exists(path):
        os.makedirs(path)
    return path


def register_blueprints(app):
    from app.api.v1 import create_blueprint_v1
    from app.api.v2 import create_blueprint_v2
    app.register_blueprint(create_blueprint_v2(), url_prefix='/v2')
    app.register_blueprint(create_blueprint_v1(), url_prefix='/v1')


def register_plugin(app):
    from app.models.base import db
    from app.models import captcha, taobao_orders, order_info, orders, paragraphs, sentence, similar_sentence, \
        xueshu_sentence, sentence_detail
    from flask_cors import CORS

    # from sshtunnel import SSHTunnelForwarder
    #
    # # SSH connection parameters
    # ssh_host = '140.143.120.186'
    # ssh_port = 22
    # ssh_user = 'ubuntu'
    # ssh_password = 'Aa19950218!'  # or use a private key
    #
    # # Database connection parameters
    # db_host = '103.7.142.131'
    # db_port = 3306  # Change this to your database port
    # db_user = 'root'
    # db_password = 'Aa19950218!'
    # db_name = 'samerpeortapi_test'
    #
    # # Set up the SSH tunnel
    # server = SSHTunnelForwarder(
    #     (ssh_host, ssh_port),
    #     ssh_username=ssh_user,
    #     ssh_password=ssh_password,  # If using a private key, remove this line
    #     remote_bind_address=(db_host, db_port)
    # )
    #
    # server.start()
    #
    # local_port = server.local_bind_port
    #
    # app.config['SQLALCHEMY_DATABASE_URI'] = (
    #     f'mysql+cymysql://{db_user}:{db_password}@127.0.0.1:{local_port}/{db_name}?charset=utf8mb4'
    # )

    CORS(app, supports_credentials=True)
    db.init_app(app)

    with app.app_context():
        db.create_all()


def register_before_request(app):
    @app.before_request
    def request_cost_time():
        g.request_start_time = time.time()
        g.request_time = lambda: "%.5f" % (time.time() - g.request_start_time)


def register_after_request(app):
    @app.after_request
    def log_response(resp):
        log_config = app.config.get('LOG')
        if not log_config['REQUEST_LOG']:
            return resp
        if request.method != 'OPTIONS':
            message = '[%s] -> [%s] from:%s costs:%.3f ms' % (
                request.method,
                request.path,
                request.remote_addr,
                float(g.request_time()) * 1000
            )
            if log_config['LEVEL'] == 'INFO':
                app.logger.info(message)
            elif log_config['LEVEL'] == 'DEBUG':
                req_body = '{}'
                try:
                    req_body = request.get_json() if request.get_json() else {}
                except:
                    pass
                message += " data:{\n\tparam: %s, \n\tbody: %s\n} " % (
                    json.dumps(request.args, ensure_ascii=False),
                    req_body
                )
                app.logger.debug(message)
        return resp


def register_logger(app):
    log_dir_name = "logs"
    log_file_name = 'logger-' + time.strftime('%Y-%m-%d', time.localtime(time.time())) + '.log'
    log_file_folder = os.path.abspath(
        os.path.join(os.path.dirname(__file__), os.pardir)) + os.sep + log_dir_name
    make_dir(log_file_folder)
    log_file_str = log_file_folder + os.sep + log_file_name
    handler = logging.FileHandler(log_file_str, encoding='UTF-8')
    handler.setLevel(logging.DEBUG)
    logging_format = logging.Formatter(
        '%(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - %(lineno)s - %(message)s')
    handler.setFormatter(logging_format)
    app.logger.addHandler(handler)


def create_app():
    app = Flask(__name__)
    app.config.from_object('app.config.setting')
    app.config.from_object('app.config.secure')
    app.config.from_object('app.config.log')
    register_after_request(app)
    register_before_request(app)
    register_plugin(app)
    register_blueprints(app)
    register_logger(app)
    return app
